module crg(
    input         clk_100m    ,
    input         rst_n       ,
    input         cpuif_mode  ,
    //50MHz
    output reg    clk_50m     ,
    output reg    rst_core_n  ,
    //100MHz
    output reg    rst_spt_n   ,
    //50MHz or 100MHz
    output        sram_clk
);

always @(posedge clk_100m) begin
    clk_50m<=~clk_50m;
end

assign sram_clk = cpuif_mode ? clk_100m : clk_50m;

// --------------------------------------------------
// rst_spt_n in 100m
// --------------------------------------------------
reg rst_n_spt_ff1, rst_n_spt_ff2;
reg [3:0]vcnt_100m;

always @(posedge clk_100m) begin
    rst_n_spt_ff1 <= rst_n;
    rst_n_spt_ff2 <= rst_n_spt_ff1;
end

wire vcnt_100m_clr = (rst_n_spt_ff1 != rst_n_spt_ff2);

always@(posedge clk_100m) begin
   if(vcnt_100m_clr)
       vcnt_100m <= 4'h0;
   else if(!rst_n_spt_ff2)
       vcnt_100m <= vcnt_100m + 1'b1;
end

always@(posedge clk_100m) begin
    rst_spt_n <= (!rst_n_spt_ff2 & vcnt_100m>=4'd9) ? 1'b0 : 1'b1;
end

// --------------------------------------------------
// rst_core_n in 50m
// --------------------------------------------------
reg rst_n_core_ff1, rst_n_core_ff2;
reg [2:0]vcnt_50m;

always @(posedge clk_50m) begin
    rst_n_core_ff1 <= rst_n;
    rst_n_core_ff2 <= rst_n_core_ff1;
end

wire vcnt_50m_clr = (rst_n_core_ff1 != rst_n_core_ff2);

always@(posedge clk_50m) begin
   if(vcnt_50m_clr)
       vcnt_50m <= 3'h0;
   else if(!rst_n_core_ff2)
       vcnt_50m <= vcnt_50m + 1'b1;
end

always@(posedge clk_50m) begin
    rst_core_n <= (!rst_n_core_ff2 & vcnt_50m>=3'd4) ? 1'b0 : 1'b1;
end

endmodule
